use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use std::collections::{HashMap, HashSet};
use std::hash::{Hash, Hasher};

/// Extension的元数据
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct Metadata {
    /// 元数据名称，全局唯一
    pub name: String,

    /// 生成名称，用于自动生成元数据名称
    #[serde(rename = "generateName", skip_serializing_if = "Option::is_none")]
    pub generate_name: Option<String>,

    /// 标签，键值对格式
    #[serde(skip_serializing_if = "Option::is_none")]
    pub labels: Option<HashMap<String, String>>,

    /// 注解，键值对格式
    #[serde(skip_serializing_if = "Option::is_none")]
    pub annotations: Option<HashMap<String, String>>,

    /// Extension的当前版本，每次更新都会递增
    #[serde(skip_serializing_if = "Option::is_none")]
    pub version: Option<i64>,

    /// Extension的创建时间戳
    #[serde(rename = "creationTimestamp", skip_serializing_if = "Option::is_none")]
    pub creation_timestamp: Option<DateTime<Utc>>,

    /// Extension的删除时间戳
    #[serde(rename = "deletionTimestamp", skip_serializing_if = "Option::is_none")]
    pub deletion_timestamp: Option<DateTime<Utc>>,

    /// 终结器列表
    #[serde(skip_serializing_if = "Option::is_none")]
    pub finalizers: Option<HashSet<String>>,
}

impl Default for Metadata {
    fn default() -> Self {
        Self {
            name: "".to_string(),
            generate_name: None,
            labels: None,
            annotations: None,
            version: None,
            creation_timestamp: None,
            deletion_timestamp: None,
            finalizers: None,
        }
    }
}

impl Metadata {
    /// 创建新的元数据实例
    pub fn new() -> Self {
        Self::default()
    }

    /// 设置名称
    pub fn with_name(mut self, name: String) -> Self {
        self.name = name;
        self
    }

    /// 设置生成名称
    pub fn with_generate_name(mut self, generate_name: String) -> Self {
        self.generate_name = Some(generate_name);
        self
    }

    /// 添加标签
    pub fn add_label(&mut self, key: String, value: String) {
        if self.labels.is_none() {
            self.labels = Some(HashMap::new());
        }
        self.labels.as_mut().unwrap().insert(key, value);
    }

    /// 添加注解
    pub fn add_annotation(&mut self, key: String, value: String) {
        if self.annotations.is_none() {
            self.annotations = Some(HashMap::new());
        }
        self.annotations.as_mut().unwrap().insert(key, value);
    }

    /// 添加终结器
    pub fn add_finalizer(&mut self, finalizer: String) {
        if self.finalizers.is_none() {
            self.finalizers = Some(HashSet::new());
        }
        self.finalizers.as_mut().unwrap().insert(finalizer);
    }

    /// 移除终结器
    pub fn remove_finalizer(&mut self, finalizer: &str) -> bool {
        if let Some(ref mut finalizers) = self.finalizers {
            finalizers.remove(finalizer)
        } else {
            false
        }
    }

    /// 检查是否被标记为删除
    pub fn is_deleted(&self) -> bool {
        self.deletion_timestamp.is_some()
    }

    /// 获取标签值
    pub fn get_label(&self, key: &str) -> Option<&String> {
        self.labels.as_ref()?.get(key)
    }

    /// 获取注解值
    pub fn get_annotation(&self, key: &str) -> Option<&String> {
        self.annotations.as_ref()?.get(key)
    }

    /// 检查是否包含终结器
    pub fn has_finalizer(&self, finalizer: &str) -> bool {
        self.finalizers
            .as_ref()
            .map(|f| f.contains(finalizer))
            .unwrap_or(false)
    }
}

impl Metadata {
    pub fn get_name(&self) -> String {
        self.name.to_string().clone()
    }

    pub fn set_name(&mut self, name: String) {
        self.name = name;
    }

    pub fn get_generate_name(&self) -> Option<String> {
        self.generate_name.clone()
    }

    pub fn set_generate_name(&mut self, name: Option<String>) {
        self.generate_name = name;
    }

    pub fn get_labels(&self) -> Option<HashMap<String, String>> {
        self.labels.clone()
    }

    pub fn set_labels(&mut self, labels: HashMap<String, String>) {
        self.labels = Some(labels);
    }

    pub fn get_annotations(&self) -> Option<HashMap<String, String>> {
        self.annotations.clone()
    }

    pub fn set_annotations(&mut self, annotations: HashMap<String, String>) {
        self.annotations = Some(annotations);
    }

    pub fn get_version(&self) -> Option<i64> {
        self.version
    }

    pub fn set_version(&mut self, version: i64) {
        self.version = Some(version);
    }

    pub fn get_creation_timestamp(&self) -> Option<DateTime<Utc>> {
        self.creation_timestamp.clone()
    }

    pub fn set_creation_timestamp(&mut self, timestamp: Option<DateTime<Utc>>) {
        self.creation_timestamp = timestamp;
    }

    pub fn get_deletion_timestamp(&self) -> Option<DateTime<Utc>> {
        self.deletion_timestamp.clone()
    }

    pub fn set_deletion_timestamp(&mut self, timestamp: DateTime<Utc>) {
        self.deletion_timestamp = Some(timestamp);
    }

    pub fn get_finalizers(&self) -> Option<HashSet<String>> {
        self.finalizers.clone()
    }

    pub fn set_finalizers(&mut self, finalizers: HashSet<String>) {
        self.finalizers = Some(finalizers);
    }
}

impl Hash for Metadata {
    fn hash<H: Hasher>(&self, state: &mut H) {
        self.name.hash(state);
        self.generate_name.hash(state);

        // self.labels.hash(state);
        hash_map(&self.labels, state);

        hash_map(&self.annotations, state);

        // self.annotations.hash(state);
        self.creation_timestamp.hash(state);
        self.deletion_timestamp.hash(state);
        if let Some(finalizers) = &self.finalizers {
            finalizers
                .iter()
                .for_each(|finalizer| finalizer.hash(state))
        };
    }
}

fn hash_map<H: Hasher>(map: &Option<HashMap<String, String>>, state: &mut H) {
    match map {
        None => 0.hash(state), // 如果为None，可以选择一个固定的值进行哈希
        Some(map) => {
            // 首先哈希map的大小
            map.len().hash(state);
            // 然后哈希map中的每个键值对
            for (key, value) in map {
                key.hash(state);
                value.hash(state);
            }
        }
    };
}
